package com.rules.admin.expression;

import com.gillion.grule.client.utils.Closure;
import com.gillion.grule.client.utils.Streams;
import com.google.common.collect.Lists;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class ExpressionFactory {
   private String defaultPackage;
   private List<String> defaultImport = Lists.newArrayList();
   private List<String> defaultAttributes = Lists.newArrayList();
   private List<String> managerImport = Lists.newArrayList();

   public RulePackageExpression createDefauleRulePackage() {
      return this.createDefauleRulePackage(this.defaultPackage, new ArrayList());
   }

   public RulePackageExpression createDefauleRulePackage(String groupId, List<ExpressionVisitor> visitors) {
      return visitors.size() > 0 ? this.getRulePackage(groupId, this.managerImport) : this.getRulePackage(groupId, this.defaultImport);
   }

   public RulePackageExpression createManagerRulePackage(String groupId) {
      return this.getRulePackage(groupId, this.managerImport);
   }

   private RulePackageExpression getRulePackage(String groupId, List<String> importLists) {
      Package packageName = new Package(groupId);
      final RulePackageExpression rulePackage = new RulePackageExpression(packageName);
      Streams.of(importLists).forEach(new Closure<String>() {
         public void execute(String s) {
            rulePackage.addImport(new Import(s));
         }
      });
      Streams.of(this.defaultAttributes).forEach(new Closure<String>() {
         public void execute(String s) {
            rulePackage.attribute(new Attribute(s));
         }
      });
      return rulePackage;
   }

   public RuleExpression createAssemblyRule() {
      RuleExpression ruleExpression = this.createDefaultRule();
      Fact ruleAssemblyFact = new Fact();
      ruleAssemblyFact.setFactAlias("$droolsRuleAssembly");
      ruleAssemblyFact.setFactObject("DroolsRuleAssembly");
      ruleExpression.addFact(ruleAssemblyFact);
      return ruleExpression;
   }

   public RuleExpression createPackageRule() {
      RuleExpression ruleExpression = this.createDefaultRule();
      Fact rulePackageFact = new Fact();
      rulePackageFact.setFactAlias("$droolsRulePackage");
      rulePackageFact.setFactObject("DroolsRulePackage");
      ruleExpression.addFact(rulePackageFact);
      return ruleExpression;
   }

   public RuleExpression createDefaultRule() {
      RuleExpression ruleExpression = new RuleExpression();
      Fact contextFact = new Fact();
      contextFact.setFactAlias("$context");
      contextFact.setFactObject("Context");
      ruleExpression.addFact(contextFact);
      ruleExpression.attribute(new Attribute("no-loop true"));
      return ruleExpression;
   }

   public Fact createDefaultFact() {
      Fact fact = new Fact();
      fact.setFactAlias("$model");
      fact.setFactObject("BusinessModel");
      return fact;
   }

   public void setDefaultPackage(String defaultPackage) {
      this.defaultPackage = defaultPackage;
   }

   public void setDefaultImport(List<String> defaultImport) {
      this.defaultImport = defaultImport;
   }

   public void setDefaultAttributes(List<String> defaultAttributes) {
      this.defaultAttributes = defaultAttributes;
   }

   public void setManagerImport(List<String> managerImport) {
      this.managerImport = managerImport;
   }
}
